﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using ASC.Models;
using System.Data.Objects.SqlClient;
using ASC.DB;
using ASC.Attributes;


using System.Web.Script.Serialization;

namespace ASC.Controllers
{
    public class ModuleController : BaseController
    {

        public ActionResult Index()
        {
             return View();
        }

        public ActionResult Add()
        {
            var moduleType = this.db.ModuleTypes.OrderBy(x=>x.Name).FirstOrDefault();
            List<ModuleTypeParameter> moduleTypeParameters = null;
            List<ModuleType_ChannelType> moduleTypeChannels = null;
            
            if(moduleType!=null)
            {
                var iModuleTypeId = moduleType.ModuleType_Id;
                moduleTypeParameters = this.db.ModuleTypeParameters.Where(x=>x.ModuleType_Id == iModuleTypeId).OrderBy(k=>k.Nr).ToList();
                moduleTypeChannels = this.db.ModuleType_ChannelType.Where(x => x.ModuleType_Id == iModuleTypeId).OrderBy(k => k.Nr).ToList();
            }

            var moduleModel = new ModuleModel()
            {
                Module = new DB.Module(),
                Parameters = moduleTypeParameters,
                ModuleTypeChannels = moduleTypeChannels,
                ChannelTypes = db.ChannelTypes.ToList(),
               
                ModuleTypes = this.db.ModuleTypes.OrderBy(x=>x.Name).ToList()
            };

            return View(moduleModel);
        }

        [HttpPost]
        public ActionResult Add(ModuleModel model, string paramsJSON, string channelsJSON)
        {
            if (!string.IsNullOrWhiteSpace(model.Module.Name))
            {
                model.Module.Config = 480;
                model.Module.Name = model.Module.Name.Trim();

                db.Modules.AddObject(model.Module);
               
                JavaScriptSerializer jss = new JavaScriptSerializer();
                var listParams = jss.Deserialize<List<Param>> (paramsJSON);

                var moduleTypeParameters = this.db.ModuleTypeParameters.Where(x => x.ModuleType_Id == model.Module.ModuleType_Id).OrderBy(k => k.Nr).ToList();

                ModuleParameter moduleParameter = null;
                foreach (var moduleTypeParameter in moduleTypeParameters)
                {
                    moduleParameter = new ModuleParameter
                    {
                        Module_Id = model.Module.Module_Id,
                        Nr = moduleTypeParameter.Nr,
                        Name = moduleTypeParameter.Name,
                        Value = listParams.FirstOrDefault(x => x.Nr == moduleTypeParameter.Nr).Value,
                        StringValue = null,
                        Unit =  moduleTypeParameter.Unit
                        
                    };
                    db.ModuleParameters.AddObject(moduleParameter);
                }
 
                if (!string.IsNullOrEmpty(channelsJSON))
                {
                    var listChannel_Nr_Ids = jss.Deserialize<List<Channel_Nr_Id>>(channelsJSON);
                    foreach (var channel_Nr_Id in listChannel_Nr_Ids)
                    {
                        db.Module_Channel.AddObject(new Module_Channel
                        {
                            Module_Id = model.Module.Module_Id,
                            Channel_Id = channel_Nr_Id.Channel_Id,
                            Nr = channel_Nr_Id.Nr
                        }
                        );
                    }
                }

                db.SaveChanges();
            }

            return RedirectToAction("Edit", new { Id = model.Module.Module_Id });
        }

        public ActionResult Edit(int Id)
        {
            var module = db.Modules.FirstOrDefault(x => x.Module_Id == Id);

            if (module != null)
            {
                var moduleType = this.db.ModuleTypes.FirstOrDefault(x => x.ModuleType_Id == module.ModuleType_Id);

                List<ModuleTypeParameter> moduleTypeParameters = null;
                List<ModuleType_ChannelType> moduleTypeChannels = null;
                List<Module_Channel> moduleChannels = null;

                moduleTypeParameters = db.ModuleTypeParameters.Where(x => x.ModuleType_Id == module.ModuleType_Id).
                    Join(db.ModuleParameters.Where(x => x.Module_Id == module.Module_Id), mTP => mTP.Nr, mP => mP.Nr, (mTP, mP) =>
                        new
                        {
                            ModuleTypeParameter = mTP,
                            ModuleParameter = mP
                        }).ToList().Select(x => new ModuleTypeParameter
                        {
                            ModuleTypeParameter_Id = x.ModuleTypeParameter.ModuleTypeParameter_Id,
                            Nr = x.ModuleTypeParameter.Nr,
                            Name = x.ModuleTypeParameter.Name,
                            Value = x.ModuleTypeParameter.Value,
                            Unit = x.ModuleTypeParameter.Unit,
                            StringValue = x.ModuleTypeParameter.StringValue,
                            ModuleType_Id = x.ModuleTypeParameter.ModuleType_Id
                        }).OrderBy(k => k.Nr).ToList();

                moduleTypeChannels = db.ModuleType_ChannelType.Where(x => x.ModuleType_Id == module.ModuleType_Id).OrderBy(k => k.Nr).ToList();

                moduleChannels = db.Module_Channel.Where(x => x.Module_Id == Id).ToList();

                var moduleModel = new ModuleModel()
                {
                    Module = module,
                    Channels = db.Channels.ToList(),
                    Module_Channels = moduleChannels,
                    ModuleTypeChannels = moduleTypeChannels,
                    ChannelTypes = db.ChannelTypes.ToList(),
                    Parameters = moduleTypeParameters,
                    ModuleTypes = db.ModuleTypes.ToList()     
                };

                return View(moduleModel);
            }
            else
            {
                return RedirectToAction("Add");
            }
        }

        [HttpPost]
        public ActionResult Edit(ModuleModel model, string paramsJSON, string channelsJSON, string IsNew)
        {
            if (IsNew == "")  //Update Mode
            {
                if (!string.IsNullOrWhiteSpace(model.Module.Name))
                {
                    var module = this.db.Modules.FirstOrDefault(x => x.Module_Id == model.Module.Module_Id);

                    module.Name = model.Module.Name.Trim();
                    module.Description = model.Module.Description;
                    module.Used = model.Module.Used;

                    foreach (var moduleParam in db.ModuleParameters.Where(x => x.Module_Id == model.Module.Module_Id))
                    {
                        db.DeleteObject(moduleParam);
                    }

                    JavaScriptSerializer jss = new JavaScriptSerializer();
                    var listParams = jss.Deserialize<List<Param>>(paramsJSON);

                    var moduleTypeParameters = this.db.ModuleTypeParameters.Where(x => x.ModuleType_Id == model.Module.ModuleType_Id).OrderBy(k => k.Nr).ToList();

                    ModuleParameter moduleParameter = null;
                    foreach (var moduleTypeParameter in moduleTypeParameters)
                    {
                        moduleParameter = new ModuleParameter
                        {
                            Module_Id = model.Module.Module_Id,
                            Nr = moduleTypeParameter.Nr,
                            Name = moduleTypeParameter.Name,
                            Value = listParams.FirstOrDefault(x => x.Nr == moduleTypeParameter.Nr).Value,
                            StringValue = null,
                            Unit = moduleTypeParameter.Unit

                        };
                        db.ModuleParameters.AddObject(moduleParameter);
                    }

                    foreach (var moduleChannel in db.Module_Channel.Where(x => x.Module_Id == model.Module.Module_Id))
                    {
                        db.DeleteObject(moduleChannel);
                    }

                    if (!string.IsNullOrEmpty(channelsJSON))
                    {
                        var listChannel_Nr_Ids = jss.Deserialize<List<Channel_Nr_Id>>(channelsJSON);
                        foreach (var channel_Nr_Id in listChannel_Nr_Ids)
                        {
                            db.Module_Channel.AddObject(new Module_Channel
                            {
                                Module_Id = model.Module.Module_Id,
                                Channel_Id = channel_Nr_Id.Channel_Id,
                                Nr = channel_Nr_Id.Nr
                            }
                            );
                        }
                    }
                    db.SaveChanges();
                }
            }
            else  //SaveAsNew Mode
            {
                if (!string.IsNullOrWhiteSpace(model.Module.Name))
                {
                    model.Module.Config = 480;
                    model.Module.Name = model.Module.Name.Trim();

                    db.Modules.AddObject(model.Module);

                    JavaScriptSerializer jss = new JavaScriptSerializer();
                    var listParams = jss.Deserialize<List<Param>>(paramsJSON);

                    var moduleTypeParameters = this.db.ModuleTypeParameters.Where(x => x.ModuleType_Id == model.Module.ModuleType_Id).OrderBy(k => k.Nr).ToList();

                    ModuleParameter moduleParameter = null;
                    foreach (var moduleTypeParameter in moduleTypeParameters)
                    {
                        moduleParameter = new ModuleParameter
                        {
                            Module_Id = model.Module.Module_Id,
                            Nr = moduleTypeParameter.Nr,
                            Name = moduleTypeParameter.Name,
                            Value = listParams.FirstOrDefault(x => x.Nr == moduleTypeParameter.Nr).Value,
                            StringValue = null,
                            Unit = moduleTypeParameter.Unit

                        };
                        db.ModuleParameters.AddObject(moduleParameter);
                    }

                    if (!string.IsNullOrEmpty(channelsJSON))
                    {
                        var listChannel_Nr_Ids = jss.Deserialize<List<Channel_Nr_Id>>(channelsJSON);
                        foreach (var channel_Nr_Id in listChannel_Nr_Ids)
                        {
                            db.Module_Channel.AddObject(new Module_Channel
                            {
                                Module_Id = model.Module.Module_Id,
                                Channel_Id = channel_Nr_Id.Channel_Id,
                                Nr = channel_Nr_Id.Nr
                            }
                            );
                        }
                    }

                    db.SaveChanges();
                }

                return RedirectToAction("Edit", new { Id = model.Module.Module_Id });
            }

            return RedirectToAction("Edit", new { Id = model.Module.Module_Id });
        }

        [HttpPost]
        public JsonResult GetModuleTypeData(int moduleTypeId)
        {
            var moduleTypeParameters = this.db.ModuleTypeParameters.Where(x => x.ModuleType_Id == moduleTypeId).OrderBy(k => k.Nr)
               .ToList().Select(x => new
               { 
                   ModuleTypeParameter_Id = x.ModuleTypeParameter_Id,
                   Nr = x.Nr,
                   Name = x.Name, 
                   Value = string.Format("{0:f2}", x.Value), 
                   Unit = x.Unit }
                   );

            
            var moduleTypeChannels = this.db.ModuleType_ChannelType.Where(x => x.ModuleType_Id == moduleTypeId).OrderBy(k => k.Nr).
                Join(db.ChannelTypes, mtct => mtct.ChannelType_Id, ct => ct.ChannelType_Id, (mtct, ct) =>
                    new
                    {
                        ModuleType_ChannelType = mtct,
                        ChannelTypes = ct
                    }).ToList().Select(x => new{
                                                    ModuleType_ChannelType_Id = x.ModuleType_ChannelType.ModuleType_ChannelType_Id,
                                                    Nr = x.ModuleType_ChannelType.Nr,
                                                    ChannelType_Id = x.ChannelTypes.ChannelType_Id,
                                                    Name = x.ModuleType_ChannelType.Name,
                                                    Description = x.ChannelTypes.Description

                                                }
                   ).OrderBy(k => k.Nr);
      
            return Json(new { Parameters = moduleTypeParameters, ModuleType_ChannelType = moduleTypeChannels });
        }

        [HttpPost]
        public JsonResult GetChannelsByChannelType(int channelTypeId)
        {
            var channels = db.Channels.Where(x => x.ChannelType_Id == channelTypeId).ToList().Select(x => new
            {
                Channel_Id = x.Channel_Id,
                ChannelName = x.Name
            });

            return Json(new { ChannelsByChannelType = channels });
        }

        [HttpPost]
        public JsonResult ValidateModuleName(string newName)
        {
               var module = db.Modules.FirstOrDefault(x=>x.Name == newName);
               if (module != null)
                   return Json(new { Exists = 1 });
               else
                   return Json(new { Exists = 0 });
        }

        [HttpPost]
        [SubmitButton]
        public ActionResult Delete(int id)
        {
            var module = db.Modules.FirstOrDefault(x => x.Module_Id == id);

            foreach (var moduleParam in db.ModuleParameters.Where(x => x.Module_Id == id))
            {
                db.DeleteObject(moduleParam);
            }

            foreach (var moduleChannel in db.Module_Channel.Where(x => x.Module_Id == id))
            {
                db.DeleteObject(moduleChannel);
            }

            this.db.DeleteObject(module);
            this.db.SaveChanges();

            return RedirectToAction("Index", "Home");
        }

    } 

    
}
